hessian2/basic_codec/class_instance_codec_unittests.cc (325 lines of code) (raw):
#include <iostream>
#include <type_traits>
#include "gtest/gtest.h"
#include "hessian2/object.hpp"
#include "hessian2/basic_codec/object_codec.hpp"
#include "hessian2/basic_codec/class_instance_codec.hpp"
#include "hessian2/basic_codec/list_codec.hpp"
#include "hessian2/basic_codec/ref_object_codec.hpp"
#include "hessian2/test_framework/decoder_test_framework.h"
#include "hessian2/test_framework/encoder_test_framework.h"
namespace Hessian2 {
class ClassInstanceTest : public testing::Test {
public:
void decodeSucc(absl::string_view data, ClassInstanceObject out) {
Hessian2::Decoder decoder(data);
auto output = decoder.decode<ClassInstanceObject>();
EXPECT_EQ(out, *output);
EXPECT_EQ(1, decoder.offset());
}
void decodeFail(absl::string_view data) {
Hessian2::Decoder decoder(data);
auto output = decoder.decode<ClassInstanceObject>();
EXPECT_EQ(nullptr, output);
}
void encodeSucc(ClassInstanceObject data, std::string expected_data = "") {
std::string res;
Hessian2::Encoder encoder(res);
encoder.encode<ClassInstanceObject>(data);
if (!expected_data.empty()) {
EXPECT_EQ(expected_data, res);
}
// decodeSucc(res, std::move(data));
}
};
TEST_F(ClassInstanceTest, InsufficientDataDecode) {
{
std::string data;
decodeFail(data);
}
{
std::string data{'C'};
decodeFail(data);
}
{
std::string data{'C', 'D'};
decodeFail(data);
}
{
std::string data{'D'};
decodeFail(data);
}
}
TEST_F(TestDecoderFramework, DecoderJavaTestCaseForClassInstance) {
{
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.A0";
ClassInstanceObject object(std::move(o));
EXPECT_TRUE(Decode<ClassInstanceObject>("replyObject_0", object));
}
{
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.TestObject";
o.def_->field_names_.emplace_back("_value");
o.data_.push_back(std::make_unique<IntegerObject>(0));
ClassInstanceObject object(std::move(o));
EXPECT_TRUE(Decode<ClassInstanceObject>("replyObject_1", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
Object::ClassInstance o2;
o2.def_ = std::make_shared<Object::RawDefinition>();
o2.def_->type_ = "com.caucho.hessian.test.TestObject";
o2.def_->field_names_.emplace_back("_value");
o2.data_.push_back(std::make_unique<IntegerObject>(1));
Object::UntypedList o;
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o2)));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Decode<UntypedListObject>("replyObject_2", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
auto o1_obj = std::make_unique<ClassInstanceObject>(std::move(o1));
auto o2_obj = std::make_unique<RefObject>(o1_obj.get());
Object::UntypedList o;
o.emplace_back(std::move(o1_obj));
o.emplace_back(std::move(o2_obj));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Decode<UntypedListObject>("replyObject_2a", object, true));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
Object::ClassInstance o2;
o2.def_ = std::make_shared<Object::RawDefinition>();
o2.def_->type_ = "com.caucho.hessian.test.TestObject";
o2.def_->field_names_.emplace_back("_value");
o2.data_.push_back(std::make_unique<IntegerObject>(0));
Object::UntypedList o;
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o2)));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Decode<UntypedListObject>("replyObject_2b", object));
}
{
ClassInstanceObject object;
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.TestCons";
o.def_->field_names_.emplace_back("_first");
o.def_->field_names_.emplace_back("_rest");
o.data_.push_back(std::make_unique<StringObject>(absl::string_view("a")));
auto o2_obj = std::make_unique<RefObject>(&object);
o.data_.push_back(std::move(o2_obj));
object.setClassInstance(std::move(o));
EXPECT_TRUE(Decode<ClassInstanceObject>("replyObject_3", object, true));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.A0";
Object::UntypedList o;
for (int i = 0; i <= 16; i++) {
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = absl::StrFormat("com.caucho.hessian.test.A%d", i);
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
}
UntypedListObject object(std::move(o));
EXPECT_TRUE(Decode<UntypedListObject>("replyObject_16", object));
}
}
TEST_F(TestEncoderFramework, EncoderJavaTestCaseForClassInstance) {
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "java.math.BigInteger";
o1.def_->field_names_.emplace_back("mag");
o1.def_->field_names_.emplace_back("firstNonzeroIntNumPlusTwo");
o1.def_->field_names_.emplace_back("lowestSetBitPlusTwo");
o1.def_->field_names_.emplace_back("bitLengthPlusOne");
o1.def_->field_names_.emplace_back("bitCountPlusOne");
o1.def_->field_names_.emplace_back("signum");
Object::TypedList o2;
o2.type_name_ = "[int";
o2.values_.emplace_back(std::make_unique<IntegerObject>(1));
o2.values_.emplace_back(std::make_unique<IntegerObject>(2));
o1.data_.emplace_back(std::make_unique<TypedListObject>(std::move(o2)));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(1));
ClassInstanceObject object(std::move(o1));
EXPECT_TRUE(
Encode<ClassInstanceObject>("customArgTypedFixed_Integer", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "java.math.BigInteger";
o1.def_->field_names_.emplace_back("mag");
o1.def_->field_names_.emplace_back("firstNonzeroIntNumPlusTwo");
o1.def_->field_names_.emplace_back("lowestSetBitPlusTwo");
o1.def_->field_names_.emplace_back("bitLengthPlusOne");
o1.def_->field_names_.emplace_back("bitCountPlusOne");
o1.def_->field_names_.emplace_back("signum");
Object::TypedList o2;
o2.type_name_ = "[int";
o2.values_.emplace_back(std::make_unique<IntegerObject>(1));
o2.values_.emplace_back(std::make_unique<IntegerObject>(2));
o1.data_.emplace_back(std::make_unique<TypedListObject>(std::move(o2)));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(0));
o1.data_.emplace_back(std::make_unique<IntegerObject>(-2));
ClassInstanceObject object(std::move(o1));
EXPECT_TRUE(Encode<ClassInstanceObject>("customArgTypedFixed_IntegerSigned",
object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "java.math.BigDecimal";
o1.def_->field_names_.emplace_back("value");
o1.data_.emplace_back(
std::make_unique<StringObject>(absl::string_view("100.256")));
ClassInstanceObject object(std::move(o1));
EXPECT_TRUE(
Encode<ClassInstanceObject>("customArgTypedFixed_Decimal", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "test.Dog";
o1.def_->field_names_.emplace_back("name");
o1.def_->field_names_.emplace_back("gender");
o1.data_.emplace_back(
std::make_unique<StringObject>(absl::string_view("a dog")));
o1.data_.emplace_back(
std::make_unique<StringObject>(absl::string_view("male")));
ClassInstanceObject object(std::move(o1));
EXPECT_TRUE(
Encode<ClassInstanceObject>("customArgTypedFixed_Extends", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "test.model.DateDemo";
o1.def_->field_names_.emplace_back("name");
o1.def_->field_names_.emplace_back("date");
o1.def_->field_names_.emplace_back("date1");
o1.data_.emplace_back(std::make_unique<NullObject>());
o1.data_.emplace_back(std::make_unique<NullObject>());
o1.data_.emplace_back(std::make_unique<NullObject>());
ClassInstanceObject object(std::move(o1));
EXPECT_TRUE(
Encode<ClassInstanceObject>("customArgTypedFixed_DateNull", object));
}
{
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.A0";
ClassInstanceObject object(std::move(o));
EXPECT_TRUE(Encode<ClassInstanceObject>("argObject_0", object));
}
{
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.TestObject";
o.def_->field_names_.emplace_back("_value");
o.data_.push_back(std::make_unique<IntegerObject>(0));
ClassInstanceObject object(std::move(o));
EXPECT_TRUE(Encode<ClassInstanceObject>("argObject_1", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
Object::ClassInstance o2;
o2.def_ = std::make_shared<Object::RawDefinition>();
o2.def_->type_ = "com.caucho.hessian.test.TestObject";
o2.def_->field_names_.emplace_back("_value");
o2.data_.push_back(std::make_unique<IntegerObject>(1));
Object::UntypedList o;
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o2)));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Encode<UntypedListObject>("argObject_2", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
auto o1_obj = std::make_unique<ClassInstanceObject>(std::move(o1));
auto o2_obj = std::make_unique<RefObject>(o1_obj.get());
Object::UntypedList o;
o.emplace_back(std::move(o1_obj));
o.emplace_back(std::move(o2_obj));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Encode<UntypedListObject>("argObject_2a", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.TestObject";
o1.def_->field_names_.emplace_back("_value");
o1.data_.push_back(std::make_unique<IntegerObject>(0));
Object::ClassInstance o2;
o2.def_ = std::make_shared<Object::RawDefinition>();
o2.def_->type_ = "com.caucho.hessian.test.TestObject";
o2.def_->field_names_.emplace_back("_value");
o2.data_.push_back(std::make_unique<IntegerObject>(0));
Object::UntypedList o;
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o2)));
UntypedListObject object(std::move(o));
EXPECT_TRUE(Encode<UntypedListObject>("argObject_2b", object));
}
{
ClassInstanceObject object;
Object::ClassInstance o;
o.def_ = std::make_shared<Object::RawDefinition>();
o.def_->type_ = "com.caucho.hessian.test.TestCons";
o.def_->field_names_.emplace_back("_first");
o.def_->field_names_.emplace_back("_rest");
o.data_.push_back(std::make_unique<StringObject>(absl::string_view("a")));
auto o2_obj = std::make_unique<RefObject>(&object);
o.data_.push_back(std::move(o2_obj));
object.setClassInstance(std::move(o));
EXPECT_TRUE(Encode<ClassInstanceObject>("argObject_3", object));
}
{
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = "com.caucho.hessian.test.A0";
Object::UntypedList o;
for (int i = 0; i <= 16; i++) {
Object::ClassInstance o1;
o1.def_ = std::make_shared<Object::RawDefinition>();
o1.def_->type_ = absl::StrFormat("com.caucho.hessian.test.A%d", i);
o.emplace_back(std::make_unique<ClassInstanceObject>(std::move(o1)));
}
UntypedListObject object(std::move(o));
EXPECT_TRUE(Encode<UntypedListObject>("argObject_16", object));
}
}
} // namespace Hessian2