blob: 9576ddcba50147391c1b6d9115042ba78ad4e2d0 [file] [log] [blame]
// 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