| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "peridot/lib/fidl/json_xdr.h" |
| |
| #include <map> |
| #include <vector> |
| |
| #include <test/peridot/lib/fidl/jsonxdr/cpp/fidl.h> |
| |
| #include "gtest/gtest.h" |
| |
| namespace modular { |
| namespace { |
| |
| namespace json_xdr_unittest = ::test::peridot::lib::fidl::jsonxdr; |
| |
| struct T { |
| int i; |
| std::string s; |
| bool b; |
| |
| std::vector<int> vi; |
| std::vector<std::string> vs; |
| std::vector<bool> vb; |
| |
| std::map<int, int> mi; |
| std::map<std::string, int> ms; |
| std::map<bool, bool> mb; |
| }; |
| |
| void XdrT_v1(XdrContext* const xdr, T* const data) { |
| xdr->Field("i", &data->i); |
| xdr->Field("s", &data->s); |
| xdr->Field("b", &data->b); |
| xdr->Field("vi", &data->vi); |
| xdr->Field("vs", &data->vs); |
| xdr->Field("vb", &data->vb); |
| xdr->Field("mi", &data->mi); |
| xdr->Field("ms", &data->ms); |
| xdr->Field("mb", &data->mb); |
| } |
| |
| constexpr XdrFilterType<T> XdrT[] = { |
| XdrT_v1, |
| nullptr, |
| }; |
| |
| TEST(Xdr, Struct) { |
| std::string json; |
| |
| T t0; |
| t0.i = 1; |
| t0.s = "2"; |
| t0.b = true; |
| t0.vi.push_back(3); |
| t0.vs.emplace_back("4"); |
| t0.vb.push_back(true); |
| t0.mi[5] = 6; |
| t0.ms["7"] = 8; |
| t0.mb[true] = false; |
| XdrWrite(&json, &t0, XdrT); |
| |
| T t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrT)); |
| |
| EXPECT_EQ(t1.i, t0.i); |
| EXPECT_EQ(t1.s, t0.s); |
| EXPECT_EQ(t1.b, t0.b); |
| EXPECT_EQ(t1.vi, t0.vi); |
| EXPECT_EQ(t1.vs, t0.vs); |
| EXPECT_EQ(t1.vb, t0.vb); |
| EXPECT_EQ(t1.mi, t0.mi); |
| EXPECT_EQ(t1.ms, t0.ms); |
| EXPECT_EQ(t1.mb, t0.mb); |
| } |
| |
| void XdrT_v2(XdrContext* const xdr, T* const data) { |
| xdr->Field("i", &data->i); |
| xdr->Field("s", &data->s); |
| xdr->Field("b", &data->b); |
| xdr->Field("vi", &data->vi); |
| xdr->Field("vs_v2", &data->vs); |
| xdr->Field("vb", &data->vb); |
| xdr->Field("mi", &data->mi); |
| xdr->Field("ms", &data->ms); |
| xdr->Field("mb", &data->mb); |
| } |
| |
| TEST(Xdr, StructVersions) { |
| // Filter versioning with version lists: Write with an old version of the |
| // filter, then attempt to read with a newer version only, which fails. |
| // Attempt again with a filter verision list that has both the old and the new |
| // version of filter, which succeeds. |
| |
| std::string json; |
| |
| T t0; |
| t0.i = 1; |
| t0.s = "2"; |
| t0.b = true; |
| t0.vi.push_back(3); |
| t0.vs.emplace_back("4"); |
| t0.vb.push_back(true); |
| t0.mi[5] = 6; |
| t0.ms["7"] = 8; |
| t0.mb[true] = false; |
| XdrWrite(&json, &t0, XdrT); |
| |
| T t1; |
| |
| constexpr XdrFilterType<T> filter_versions_v2_only[] = { |
| XdrT_v2, |
| nullptr, |
| }; |
| |
| EXPECT_FALSE(XdrRead(json, &t1, filter_versions_v2_only)); |
| |
| constexpr XdrFilterType<T> filter_versions_all[] = { |
| XdrT_v2, |
| XdrT_v1, |
| nullptr, |
| }; |
| |
| EXPECT_TRUE(XdrRead(json, &t1, filter_versions_all)); |
| } |
| |
| void XdrT_v3(XdrContext* const xdr, T* const data) { |
| if (!xdr->Version(3)) { |
| return; |
| } |
| |
| xdr->Field("i", &data->i); |
| xdr->Field("s", &data->s); |
| xdr->Field("b", &data->b); |
| xdr->Field("vi", &data->vi); |
| xdr->Field("vs", &data->vs); |
| xdr->Field("vb", &data->vb); |
| xdr->Field("mi", &data->mi); |
| xdr->Field("ms", &data->ms); |
| xdr->Field("mb", &data->mb); |
| } |
| |
| TEST(Xdr, StructVersionsExplicitFallback) { |
| // Filter versioning with explicit version numbers: Write with an old version |
| // of the filter without version number, then attempt to read with a filter |
| // that expects a version number, which fails. Attempt again with a filter |
| // version list that has both the old and the new version of filter, which |
| // succeeds. |
| |
| std::string json; |
| |
| T t0; |
| t0.i = 1; |
| t0.s = "2"; |
| t0.b = true; |
| t0.vi.push_back(3); |
| t0.vs.emplace_back("4"); |
| t0.vb.push_back(true); |
| t0.mi[5] = 6; |
| t0.ms["7"] = 8; |
| t0.mb[true] = false; |
| XdrWrite(&json, &t0, XdrT); |
| |
| T t1; |
| |
| constexpr XdrFilterType<T> filter_versions_v3_only[] = { |
| XdrT_v3, |
| nullptr, |
| }; |
| |
| EXPECT_FALSE(XdrRead(json, &t1, filter_versions_v3_only)); |
| |
| constexpr XdrFilterType<T> filter_versions_all[] = { |
| XdrT_v3, |
| XdrT_v1, |
| nullptr, |
| }; |
| |
| EXPECT_TRUE(XdrRead(json, &t1, filter_versions_all)); |
| } |
| |
| void XdrT_v4(XdrContext* const xdr, T* const data) { |
| if (!xdr->Version(4)) { |
| return; |
| } |
| |
| xdr->Field("i", &data->i); |
| xdr->Field("s", &data->s); |
| xdr->Field("b", &data->b); |
| xdr->Field("vi", &data->vi); |
| xdr->Field("vs", &data->vs); |
| xdr->Field("vb", &data->vb); |
| xdr->Field("mi", &data->mi); |
| xdr->Field("ms", &data->ms); |
| xdr->Field("mb", &data->mb); |
| } |
| |
| TEST(Xdr, StructVersionsExplicit) { |
| // Filter versioning with explicit version numbers: Write with a version of |
| // the filter with a version number, then attempt to read it back with the |
| // same filter, which succeeds. Attempt to read it with a newer version |
| // filter, which fails. |
| |
| std::string json; |
| |
| constexpr XdrFilterType<T> filter_versions_v3_only[] = { |
| XdrT_v3, |
| nullptr, |
| }; |
| |
| T t0; |
| t0.i = 1; |
| t0.s = "2"; |
| t0.b = true; |
| t0.vi.push_back(3); |
| t0.vs.emplace_back("4"); |
| t0.vb.push_back(true); |
| t0.mi[5] = 6; |
| t0.ms["7"] = 8; |
| t0.mb[true] = false; |
| XdrWrite(&json, &t0, filter_versions_v3_only); |
| |
| T t1; |
| EXPECT_TRUE(XdrRead(json, &t1, filter_versions_v3_only)); |
| |
| constexpr XdrFilterType<T> filter_versions_v4_only[] = { |
| XdrT_v4, |
| nullptr, |
| }; |
| |
| T t2; |
| EXPECT_FALSE(XdrRead(json, &t2, filter_versions_v4_only)); |
| |
| constexpr XdrFilterType<T> filter_versions_all[] = { |
| XdrT_v4, XdrT_v3, XdrT_v2, XdrT_v1, nullptr, |
| }; |
| |
| T t3; |
| EXPECT_TRUE(XdrRead(json, &t3, filter_versions_all)); |
| } |
| |
| void XdrStruct(XdrContext* const xdr, json_xdr_unittest::Struct* const data) { |
| xdr->Field("item", &data->item); |
| } |
| |
| void XdrUnion(XdrContext* const xdr, json_xdr_unittest::Union* const data) { |
| // NOTE(mesch): There is no direct support for FIDL unions in XdrContext, |
| // mostly because we cannot point a union field in the same way s we can point |
| // to a struct field. |
| // |
| // The below is the current best way we have figured out to XDR unions. A |
| // lager and more realistic (and slightly different) real life example of |
| // XDRing a FIDL union type is XdrNoun() in story_controller_impl.cc. |
| |
| static constexpr char kTag[] = "@tag"; |
| static constexpr char kValue[] = "@value"; |
| static constexpr char kString[] = "string"; |
| static constexpr char kInt32[] = "int32"; |
| |
| switch (xdr->op()) { |
| case XdrOp::FROM_JSON: { |
| std::string tag; |
| xdr->Field(kTag, &tag); |
| |
| if (tag == kString) { |
| std::string value; |
| xdr->Field(kValue, &value); |
| data->set_string(std::move(value)); |
| |
| } else if (tag == kInt32) { |
| int32_t value; |
| xdr->Field(kValue, &value); |
| data->set_int32(std::move(value)); |
| |
| } else { |
| ASSERT_TRUE(false) << "XdrUnion FROM_JSON unknown tag: " << tag; |
| } |
| break; |
| } |
| |
| case XdrOp::TO_JSON: { |
| std::string tag; |
| |
| switch (data->Which()) { |
| case json_xdr_unittest::Union::Tag::kString: { |
| tag = kString; |
| std::string value = data->string(); |
| xdr->Field(kValue, &value); |
| break; |
| } |
| case json_xdr_unittest::Union::Tag::kInt32: { |
| tag = kInt32; |
| int32_t value = data->int32(); |
| xdr->Field(kValue, &value); |
| break; |
| } |
| case json_xdr_unittest::Union::Tag::Invalid: |
| ASSERT_TRUE(false) << "XdrUnion TO_JSON unknown tag: " |
| << static_cast<int>(data->Which()); |
| break; |
| } |
| |
| xdr->Field(kTag, &tag); |
| break; |
| } |
| } |
| } |
| |
| // Data can be any of RequiredData, RequiredRepeatedRequiredData, |
| // OptionalRepeatedRequiredData. |
| template <typename Data> |
| void XdrRequiredData_v1(XdrContext* const xdr, Data* const data) { |
| xdr->Field("string", &data->string); |
| xdr->Field("bool", &data->bool_); |
| xdr->Field("int8", &data->int8); |
| xdr->Field("int16", &data->int16); |
| xdr->Field("int32", &data->int32); |
| xdr->Field("int64", &data->int64); |
| xdr->Field("uint8", &data->uint8); |
| xdr->Field("uint16", &data->uint16); |
| xdr->Field("uint32", &data->uint32); |
| xdr->Field("uint64", &data->uint64); |
| xdr->Field("float32", &data->float32); |
| xdr->Field("float64", &data->float64); |
| xdr->Field("struct", &data->struct_, XdrStruct); |
| xdr->Field("enum", &data->enum_); |
| xdr->Field("union", &data->union_, XdrUnion); |
| } |
| |
| // Data can be any of OptionalData, RequiredRepeatedOptionalData, |
| // OptionalRepeatedOptionalData. |
| template <typename Data> |
| void XdrOptionalData_v1(XdrContext* const xdr, Data* const data) { |
| xdr->Field("string", &data->string); |
| xdr->Field("struct", &data->struct_, XdrStruct); |
| xdr->Field("union", &data->union_, XdrUnion); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::RequiredData> XdrRequiredData[] = { |
| XdrRequiredData_v1<json_xdr_unittest::RequiredData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlRequired) { |
| std::string json; |
| |
| json_xdr_unittest::RequiredData t0; |
| |
| t0.string = "1"; |
| t0.bool_ = true; |
| t0.int8 = 2; |
| t0.int16 = 3; |
| t0.int32 = 4; |
| t0.int64 = 5; |
| t0.uint8 = 6; |
| t0.uint16 = 7; |
| t0.uint32 = 8; |
| t0.uint64 = 9; |
| t0.float32 = 10; |
| t0.float64 = 11; |
| t0.struct_.item = 12; |
| t0.enum_ = json_xdr_unittest::Enum::ONE; |
| t0.union_.set_int32(13); |
| |
| XdrWrite(&json, &t0, XdrRequiredData); |
| |
| json_xdr_unittest::RequiredData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| // Technically not needed because the equality should cover this, but makes it |
| // more transparent what's going on. |
| EXPECT_EQ("1", t1.string); |
| EXPECT_TRUE(t1.bool_); |
| EXPECT_EQ(2, t1.int8); |
| EXPECT_EQ(3, t1.int16); |
| EXPECT_EQ(4, t1.int32); |
| EXPECT_EQ(5, t1.int64); |
| EXPECT_EQ(6u, t1.uint8); |
| EXPECT_EQ(7u, t1.uint16); |
| EXPECT_EQ(8u, t1.uint32); |
| EXPECT_EQ(9u, t1.uint64); |
| EXPECT_EQ(10.0f, t1.float32); |
| EXPECT_EQ(11.0, t1.float64); |
| EXPECT_EQ(12, t1.struct_.item); |
| EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_); |
| EXPECT_TRUE(t1.union_.is_int32()); |
| EXPECT_EQ(13, t1.union_.int32()); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::OptionalData> XdrOptionalData[] = { |
| XdrOptionalData_v1<json_xdr_unittest::OptionalData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlOptional) { |
| std::string json; |
| |
| json_xdr_unittest::OptionalData t0; |
| |
| t0.string = "1"; |
| t0.struct_ = json_xdr_unittest::Struct::New(); |
| t0.struct_->item = 12; |
| t0.union_ = json_xdr_unittest::Union::New(); |
| t0.union_->set_int32(13); |
| |
| XdrWrite(&json, &t0, XdrOptionalData); |
| |
| json_xdr_unittest::OptionalData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_FALSE(t1.string.is_null()); |
| EXPECT_EQ("1", t1.string); |
| |
| EXPECT_FALSE(nullptr == t1.struct_); |
| EXPECT_EQ(12, t1.struct_->item); |
| |
| EXPECT_FALSE(nullptr == t1.union_); |
| EXPECT_TRUE(t1.union_->is_int32()); |
| EXPECT_EQ(13, t1.union_->int32()); |
| |
| t1.string.reset(); |
| t1.struct_.reset(); |
| t1.union_.reset(); |
| |
| XdrWrite(&json, &t1, XdrOptionalData); |
| |
| json_xdr_unittest::OptionalData t2; |
| EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalData)); |
| |
| EXPECT_EQ(t2, t1) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_TRUE(t2.string.is_null()); |
| EXPECT_TRUE(nullptr == t2.struct_); |
| EXPECT_TRUE(nullptr == t2.union_); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::RequiredRepeatedRequiredData> |
| XdrRequiredRepeatedRequiredData[] = { |
| XdrRequiredData_v1<json_xdr_unittest::RequiredRepeatedRequiredData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlRequiredRepeatedRequired) { |
| std::string json; |
| |
| json_xdr_unittest::RequiredRepeatedRequiredData t0; |
| |
| t0.string.push_back("1"); |
| t0.bool_.push_back(true); |
| t0.int8.push_back(2); |
| t0.int16.push_back(3); |
| t0.int32.push_back(4); |
| t0.int64.push_back(5); |
| t0.uint8.push_back(6); |
| t0.uint16.push_back(7); |
| t0.uint32.push_back(8); |
| t0.uint64.push_back(9); |
| t0.float32.push_back(10); |
| t0.float64.push_back(11); |
| t0.struct_.push_back({12}); |
| t0.enum_.push_back(json_xdr_unittest::Enum::ONE); |
| |
| json_xdr_unittest::Union u; |
| u.set_int32(13); |
| t0.union_.push_back(std::move(u)); |
| |
| XdrWrite(&json, &t0, XdrRequiredRepeatedRequiredData); |
| |
| json_xdr_unittest::RequiredRepeatedRequiredData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredRepeatedRequiredData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| EXPECT_EQ(1u, t1.string.size()); |
| EXPECT_EQ(1u, t1.bool_.size()); |
| EXPECT_EQ(1u, t1.int8.size()); |
| EXPECT_EQ(1u, t1.int16.size()); |
| EXPECT_EQ(1u, t1.int32.size()); |
| EXPECT_EQ(1u, t1.int64.size()); |
| EXPECT_EQ(1u, t1.uint8.size()); |
| EXPECT_EQ(1u, t1.uint16.size()); |
| EXPECT_EQ(1u, t1.uint32.size()); |
| EXPECT_EQ(1u, t1.uint64.size()); |
| EXPECT_EQ(1u, t1.float32.size()); |
| EXPECT_EQ(1u, t1.float64.size()); |
| EXPECT_EQ(1u, t1.struct_.size()); |
| EXPECT_EQ(1u, t1.enum_.size()); |
| EXPECT_EQ(1u, t1.union_.size()); |
| |
| EXPECT_EQ("1", t1.string.at(0)); |
| EXPECT_TRUE(t1.bool_.at(0)); |
| EXPECT_EQ(2, t1.int8.at(0)); |
| EXPECT_EQ(3, t1.int16.at(0)); |
| EXPECT_EQ(4, t1.int32.at(0)); |
| EXPECT_EQ(5, t1.int64.at(0)); |
| EXPECT_EQ(6u, t1.uint8.at(0)); |
| EXPECT_EQ(7u, t1.uint16.at(0)); |
| EXPECT_EQ(8u, t1.uint32.at(0)); |
| EXPECT_EQ(9u, t1.uint64.at(0)); |
| EXPECT_EQ(10.0f, t1.float32.at(0)); |
| EXPECT_EQ(11.0, t1.float64.at(0)); |
| EXPECT_EQ(12, t1.struct_.at(0).item); |
| EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_.at(0)); |
| EXPECT_TRUE(t1.union_.at(0).is_int32()); |
| EXPECT_EQ(13, t1.union_.at(0).int32()); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::RequiredRepeatedOptionalData> |
| XdrRequiredRepeatedOptionalData[] = { |
| XdrOptionalData_v1<json_xdr_unittest::RequiredRepeatedOptionalData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlRequiredRepeatedOptional) { |
| std::string json; |
| |
| json_xdr_unittest::RequiredRepeatedOptionalData t0; |
| t0.string.push_back("1"); |
| |
| json_xdr_unittest::StructPtr s = json_xdr_unittest::Struct::New(); |
| s->item = 12; |
| t0.struct_.push_back(std::move(s)); |
| |
| json_xdr_unittest::UnionPtr u = json_xdr_unittest::Union::New(); |
| u->set_int32(13); |
| t0.union_.push_back(std::move(u)); |
| |
| XdrWrite(&json, &t0, XdrRequiredRepeatedOptionalData); |
| |
| json_xdr_unittest::RequiredRepeatedOptionalData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredRepeatedOptionalData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_EQ(1u, t1.string.size()); |
| EXPECT_EQ(1u, t1.struct_.size()); |
| EXPECT_EQ(1u, t1.union_.size()); |
| |
| EXPECT_FALSE(t1.string.at(0).is_null()); |
| EXPECT_EQ("1", t1.string.at(0)); |
| |
| EXPECT_FALSE(nullptr == t1.struct_.at(0)); |
| EXPECT_EQ(12, t1.struct_.at(0)->item); |
| |
| EXPECT_FALSE(nullptr == t1.union_.at(0)); |
| EXPECT_TRUE(t1.union_.at(0)->is_int32()); |
| EXPECT_EQ(13, t1.union_.at(0)->int32()); |
| |
| t1.string.at(0).reset(); |
| t1.struct_.at(0).reset(); |
| t1.union_.at(0).reset(); |
| |
| XdrWrite(&json, &t1, XdrRequiredRepeatedOptionalData); |
| |
| json_xdr_unittest::RequiredRepeatedOptionalData t2; |
| EXPECT_TRUE(XdrRead(json, &t2, XdrRequiredRepeatedOptionalData)); |
| |
| EXPECT_EQ(t2, t1) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_EQ(1u, t2.string.size()); |
| EXPECT_EQ(1u, t2.struct_.size()); |
| EXPECT_EQ(1u, t2.union_.size()); |
| |
| EXPECT_TRUE(t2.string.at(0).is_null()); |
| EXPECT_TRUE(nullptr == t2.struct_.at(0)); |
| EXPECT_TRUE(nullptr == t2.union_.at(0)); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::OptionalRepeatedRequiredData> |
| XdrOptionalRepeatedRequiredData[] = { |
| XdrRequiredData_v1<json_xdr_unittest::OptionalRepeatedRequiredData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlOptionalRepeatedRequired) { |
| std::string json; |
| |
| json_xdr_unittest::OptionalRepeatedRequiredData t0; |
| |
| t0.string.push_back("1"); |
| t0.bool_.push_back(true); |
| t0.int8.push_back(2); |
| t0.int16.push_back(3); |
| t0.int32.push_back(4); |
| t0.int64.push_back(5); |
| t0.uint8.push_back(6); |
| t0.uint16.push_back(7); |
| t0.uint32.push_back(8); |
| t0.uint64.push_back(9); |
| t0.float32.push_back(10); |
| t0.float64.push_back(11); |
| t0.struct_.push_back({12}); |
| t0.enum_.push_back(json_xdr_unittest::Enum::ONE); |
| json_xdr_unittest::Union u; |
| u.set_int32(13); |
| t0.union_.push_back(std::move(u)); |
| |
| XdrWrite(&json, &t0, XdrOptionalRepeatedRequiredData); |
| |
| json_xdr_unittest::OptionalRepeatedRequiredData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalRepeatedRequiredData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| EXPECT_FALSE(t1.string.is_null()); |
| EXPECT_FALSE(t1.bool_.is_null()); |
| EXPECT_FALSE(t1.int8.is_null()); |
| EXPECT_FALSE(t1.int16.is_null()); |
| EXPECT_FALSE(t1.int32.is_null()); |
| EXPECT_FALSE(t1.int64.is_null()); |
| EXPECT_FALSE(t1.uint8.is_null()); |
| EXPECT_FALSE(t1.uint16.is_null()); |
| EXPECT_FALSE(t1.uint32.is_null()); |
| EXPECT_FALSE(t1.uint64.is_null()); |
| EXPECT_FALSE(t1.float32.is_null()); |
| EXPECT_FALSE(t1.float64.is_null()); |
| EXPECT_FALSE(t1.struct_.is_null()); |
| EXPECT_FALSE(t1.enum_.is_null()); |
| EXPECT_FALSE(t1.union_.is_null()); |
| |
| EXPECT_EQ(1u, t1.string->size()); |
| EXPECT_EQ(1u, t1.bool_->size()); |
| EXPECT_EQ(1u, t1.int8->size()); |
| EXPECT_EQ(1u, t1.int16->size()); |
| EXPECT_EQ(1u, t1.int32->size()); |
| EXPECT_EQ(1u, t1.int64->size()); |
| EXPECT_EQ(1u, t1.uint8->size()); |
| EXPECT_EQ(1u, t1.uint16->size()); |
| EXPECT_EQ(1u, t1.uint32->size()); |
| EXPECT_EQ(1u, t1.uint64->size()); |
| EXPECT_EQ(1u, t1.float32->size()); |
| EXPECT_EQ(1u, t1.float64->size()); |
| EXPECT_EQ(1u, t1.struct_->size()); |
| EXPECT_EQ(1u, t1.enum_->size()); |
| EXPECT_EQ(1u, t1.union_->size()); |
| |
| EXPECT_EQ("1", t1.string->at(0)); |
| EXPECT_TRUE(t1.bool_->at(0)); |
| EXPECT_EQ(2, t1.int8->at(0)); |
| EXPECT_EQ(3, t1.int16->at(0)); |
| EXPECT_EQ(4, t1.int32->at(0)); |
| EXPECT_EQ(5, t1.int64->at(0)); |
| EXPECT_EQ(6u, t1.uint8->at(0)); |
| EXPECT_EQ(7u, t1.uint16->at(0)); |
| EXPECT_EQ(8u, t1.uint32->at(0)); |
| EXPECT_EQ(9u, t1.uint64->at(0)); |
| EXPECT_EQ(10.0f, t1.float32->at(0)); |
| EXPECT_EQ(11.0, t1.float64->at(0)); |
| EXPECT_EQ(12, t1.struct_->at(0).item); |
| EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_->at(0)); |
| EXPECT_TRUE(t1.union_->at(0).is_int32()); |
| EXPECT_EQ(13, t1.union_->at(0).int32()); |
| |
| t1.string.reset(); |
| t1.bool_.reset(); |
| t1.int8.reset(); |
| t1.int16.reset(); |
| t1.int32.reset(); |
| t1.int64.reset(); |
| t1.uint8.reset(); |
| t1.uint16.reset(); |
| t1.uint32.reset(); |
| t1.uint64.reset(); |
| t1.float32.reset(); |
| t1.float64.reset(); |
| t1.struct_.reset(); |
| t1.enum_.reset(); |
| t1.union_.reset(); |
| |
| XdrWrite(&json, &t1, XdrOptionalRepeatedRequiredData); |
| |
| json_xdr_unittest::OptionalRepeatedRequiredData t2; |
| EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalRepeatedRequiredData)); |
| |
| EXPECT_EQ(t2, t1) << json; |
| |
| EXPECT_TRUE(t2.string.is_null()); |
| EXPECT_TRUE(t2.bool_.is_null()); |
| EXPECT_TRUE(t2.int8.is_null()); |
| EXPECT_TRUE(t2.int16.is_null()); |
| EXPECT_TRUE(t2.int32.is_null()); |
| EXPECT_TRUE(t2.int64.is_null()); |
| EXPECT_TRUE(t2.uint8.is_null()); |
| EXPECT_TRUE(t2.uint16.is_null()); |
| EXPECT_TRUE(t2.uint32.is_null()); |
| EXPECT_TRUE(t2.uint64.is_null()); |
| EXPECT_TRUE(t2.float32.is_null()); |
| EXPECT_TRUE(t2.float64.is_null()); |
| EXPECT_TRUE(t2.struct_.is_null()); |
| EXPECT_TRUE(t2.enum_.is_null()); |
| EXPECT_TRUE(t2.union_.is_null()); |
| |
| EXPECT_EQ(0u, t2.string->size()); |
| EXPECT_EQ(0u, t2.bool_->size()); |
| EXPECT_EQ(0u, t2.int8->size()); |
| EXPECT_EQ(0u, t2.int16->size()); |
| EXPECT_EQ(0u, t2.int32->size()); |
| EXPECT_EQ(0u, t2.int64->size()); |
| EXPECT_EQ(0u, t2.uint8->size()); |
| EXPECT_EQ(0u, t2.uint16->size()); |
| EXPECT_EQ(0u, t2.uint32->size()); |
| EXPECT_EQ(0u, t2.uint64->size()); |
| EXPECT_EQ(0u, t2.float32->size()); |
| EXPECT_EQ(0u, t2.float64->size()); |
| EXPECT_EQ(0u, t2.struct_->size()); |
| EXPECT_EQ(0u, t2.enum_->size()); |
| EXPECT_EQ(0u, t2.union_->size()); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::OptionalRepeatedOptionalData> |
| XdrOptionalRepeatedOptionalData[] = { |
| XdrOptionalData_v1<json_xdr_unittest::OptionalRepeatedOptionalData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlOptionalRepeatedOptional) { |
| std::string json; |
| |
| json_xdr_unittest::OptionalRepeatedOptionalData t0; |
| t0.string.push_back("1"); |
| |
| json_xdr_unittest::StructPtr s = json_xdr_unittest::Struct::New(); |
| s->item = 12; |
| t0.struct_.push_back(std::move(s)); |
| |
| json_xdr_unittest::UnionPtr u = json_xdr_unittest::Union::New(); |
| u->set_int32(13); |
| t0.union_.push_back(std::move(u)); |
| |
| XdrWrite(&json, &t0, XdrOptionalRepeatedOptionalData); |
| |
| json_xdr_unittest::OptionalRepeatedOptionalData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalRepeatedOptionalData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_FALSE(t1.string.is_null()); |
| EXPECT_FALSE(t1.struct_.is_null()); |
| EXPECT_FALSE(t1.union_.is_null()); |
| |
| EXPECT_EQ(1u, t1.string->size()); |
| EXPECT_EQ(1u, t1.struct_->size()); |
| EXPECT_EQ(1u, t1.union_->size()); |
| |
| EXPECT_FALSE(t1.string->at(0).is_null()); |
| EXPECT_EQ("1", t1.string->at(0)); |
| |
| EXPECT_FALSE(nullptr == t1.struct_->at(0)); |
| EXPECT_EQ(12, t1.struct_->at(0)->item); |
| |
| EXPECT_FALSE(nullptr == t1.union_->at(0)); |
| EXPECT_TRUE(t1.union_->at(0)->is_int32()); |
| EXPECT_EQ(13, t1.union_->at(0)->int32()); |
| |
| t1.string->at(0).reset(); |
| t1.struct_->at(0).reset(); |
| t1.union_->at(0).reset(); |
| |
| XdrWrite(&json, &t1, XdrOptionalRepeatedOptionalData); |
| |
| json_xdr_unittest::OptionalRepeatedOptionalData t2; |
| EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalRepeatedOptionalData)); |
| |
| EXPECT_EQ(t2, t1) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_FALSE(t2.string.is_null()); |
| EXPECT_FALSE(t2.struct_.is_null()); |
| EXPECT_FALSE(t2.union_.is_null()); |
| |
| EXPECT_EQ(1u, t2.string->size()); |
| EXPECT_EQ(1u, t2.struct_->size()); |
| EXPECT_EQ(1u, t2.union_->size()); |
| |
| EXPECT_TRUE(t2.string->at(0).is_null()); |
| EXPECT_TRUE(nullptr == t2.struct_->at(0)); |
| EXPECT_TRUE(nullptr == t2.union_->at(0)); |
| |
| t2.string.reset(); |
| t2.struct_.reset(); |
| t2.union_.reset(); |
| |
| XdrWrite(&json, &t2, XdrOptionalRepeatedOptionalData); |
| |
| json_xdr_unittest::OptionalRepeatedOptionalData t3; |
| EXPECT_TRUE(XdrRead(json, &t3, XdrOptionalRepeatedOptionalData)); |
| |
| EXPECT_EQ(t3, t2) << json; |
| |
| // See comment in FidlRequired. |
| EXPECT_TRUE(t3.string.is_null()); |
| EXPECT_TRUE(t3.struct_.is_null()); |
| EXPECT_TRUE(t3.union_.is_null()); |
| |
| EXPECT_EQ(0u, t3.string->size()); |
| EXPECT_EQ(0u, t3.struct_->size()); |
| EXPECT_EQ(0u, t3.union_->size()); |
| } |
| |
| constexpr XdrFilterType<json_xdr_unittest::ArrayData> XdrArrayData[] = { |
| XdrRequiredData_v1<json_xdr_unittest::ArrayData>, |
| nullptr, |
| }; |
| |
| TEST(Xdr, FidlArray) { |
| std::string json; |
| |
| json_xdr_unittest::ArrayData t0; |
| |
| for (size_t i=0; i<t0.string.size(); i++) { |
| t0.string.at(i) = "1"; |
| t0.bool_.at(i) = true; |
| t0.int8.at(i) = 2; |
| t0.int16.at(i) = 3; |
| t0.int32.at(i) = 4; |
| t0.int64.at(i) = 5; |
| t0.uint8.at(i) = 6; |
| t0.uint16.at(i) = 7; |
| t0.uint32.at(i) = 8; |
| t0.uint64.at(i) = 9; |
| t0.float32.at(i) = 10; |
| t0.float64.at(i) = 11; |
| t0.struct_.at(i).item = 12; |
| t0.enum_.at(i) = json_xdr_unittest::Enum::ONE; |
| t0.union_.at(i).set_int32(13); |
| } |
| |
| XdrWrite(&json, &t0, XdrArrayData); |
| |
| json_xdr_unittest::ArrayData t1; |
| EXPECT_TRUE(XdrRead(json, &t1, XdrArrayData)); |
| |
| EXPECT_EQ(t1, t0) << json; |
| |
| // Technically not needed because the equality should cover this, but makes it |
| // more transparent what's going on. |
| EXPECT_EQ("1", t1.string.at(0)); |
| EXPECT_TRUE(t1.bool_.at(0)); |
| EXPECT_EQ(2, t1.int8.at(0)); |
| EXPECT_EQ(3, t1.int16.at(0)); |
| EXPECT_EQ(4, t1.int32.at(0)); |
| EXPECT_EQ(5, t1.int64.at(0)); |
| EXPECT_EQ(6u, t1.uint8.at(0)); |
| EXPECT_EQ(7u, t1.uint16.at(0)); |
| EXPECT_EQ(8u, t1.uint32.at(0)); |
| EXPECT_EQ(9u, t1.uint64.at(0)); |
| EXPECT_EQ(10.0f, t1.float32.at(0)); |
| EXPECT_EQ(11.0, t1.float64.at(0)); |
| EXPECT_EQ(12, t1.struct_.at(0).item); |
| EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_.at(0)); |
| EXPECT_TRUE(t1.union_.at(0).is_int32()); |
| EXPECT_EQ(13, t1.union_.at(0).int32()); |
| } |
| |
| } // namespace |
| } // namespace modular |